﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Security.Cryptography;
using Microsoft.Win32;
using SecureCommander.Core;
using System.IO;
using SecureCommander.Helper;
using SecureCommander.Core.UserManagement;
using SecureCommander.DataAccess;
using Ionic.Zip;
using SecureCommander.Core.SecurityManager;

namespace SecureCommander.GUI
{
    /// <summary>
    /// Interaction logic for FormEncrypt.xaml
    /// </summary>
    public partial class FormEncrypt : Window
    {
        public string StartDirectory { get; set; }
        private byte[] KeyByte;
        private byte[] IvByte;

        public FormEncrypt()
        {
            InitializeComponent();
        }

        private bool IsInList(FileInfo file)
        {
            foreach (ListViewContent row in gridSelectedFiles.Items)
            {
                if (row.Tag.FullName.Equals(file.FullName))
                {
                    return true;
                }
            }
            return false;
        }

        private void btnAddFile_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Multiselect = true;
            if (dlg.ShowDialog().Value)
            {
                foreach (string fileName in dlg.FileNames)
                {
                    FileInfo file = new FileInfo(fileName);
                    if (!IsInList(file))
                    {
                        this.gridSelectedFiles.Items.Add(new ListViewContent(file.Name,
                                                                    file.Length.ToString(),
                                                                    file.LastWriteTime.ToString(),
                                                                    NativeMethods.getTypeName(file.FullName),
                                                                    FileHelper.IconManager.GetFileImage(file.FullName),
                                                                    FileHelper.GetAtributeString(file.Attributes),
                                                                    file));
                    }
                }




            }
        }

        private void btnAddFolder_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog dlg = new System.Windows.Forms.FolderBrowserDialog();
            dlg.SelectedPath = StartDirectory;
            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                DirectoryInfo dir = new DirectoryInfo(dlg.SelectedPath);
                this.gridSelectedFiles.Items.Add(new ListViewContent(dir.Name,
                                                                "",
                                                                dir.LastWriteTime.ToString(),
                                                                "File Folder",
                                                                FileHelper.IconManager.GetFolderIcon(dir.FullName),
                                                                FileHelper.GetAtributeString(dir.Attributes),
                                                                dir));
            }
        }

        private void btnBrowse_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog saveDialog = new SaveFileDialog();
            saveDialog.InitialDirectory = StartDirectory;
            saveDialog.Filter = "Ecrypted File|*.enc";
            if (saveDialog.ShowDialog().Value)
            {
                txtDesination.Text = saveDialog.FileName;
            }
        }

        private void btnOK_Click(object sender, RoutedEventArgs e)
        {
            if (txtDesination.Text == "" || !Directory.Exists(txtDesination.Text.Substring(0, txtDesination.Text.LastIndexOf("\\"))))
            {
                FileHelper.ShowMessage("Please select output path again!", MessageBoxImage.Warning);
                return;
            }


            if (gridSelectedFiles.Items.Count <= 0)
            {
                FileHelper.ShowMessage("Please select file(s) or folder(s) to encrypt!", MessageBoxImage.Warning);
                return;
            }
            UserInfo User = (UserInfo) cbbUser.SelectedItem;
            
            RSACryptoServiceProvider Rsa = new RSACryptoServiceProvider();
            Rsa.FromXmlString(User.Publickey);

            string outputFilePath = txtDesination.Text;
            string inputFilePath = outputFilePath.Substring(0, outputFilePath.LastIndexOf(".")) + ".zip";
            
            ZipFile zip = new ZipFile();
            foreach (ListViewContent row in gridSelectedFiles.Items)
            {
                if (row.Tag is DirectoryInfo)
                {
                    zip.AddDirectory(row.Tag.FullName, "\\");
                }
                else
                {
                    zip.AddFile(row.Tag.FullName, "\\");
                }
            }
            zip.Save(inputFilePath);
            zip.Dispose();

            /************************/
            string tempFile = inputFilePath;

            if (txtDesination.Text == "")
            {
                FileHelper.ShowMessage("Please fill information required!", MessageBoxImage.Error);
            }
            try
            {
                PaddingMode pad = (PaddingMode)cbbPaddingSchema.SelectedItem;
                CipherMode cipher = (CipherMode)cbbOperationMode.SelectedItem;
                int Zip = 0;
                if (cbZip.IsChecked.Value)
                {
                    Zip = 1;
                }


                if (cbbAlgorithm.SelectedItem.Equals("DES"))
                {
                    DesAlgorithm DesAgl = new DesAlgorithm(pad, cipher);

                    DesAgl.EncryptFile(inputFilePath, outputFilePath);
                    KeyByte = Rsa.Encrypt(DesAgl.Key, false);
                    IvByte = Rsa.Encrypt(DesAgl.IV, false);
                }

                if (cbbAlgorithm.SelectedItem.Equals("TripleDES"))
                {
                    TripleDesAlgorithm TripleAgl = new TripleDesAlgorithm(pad, cipher);
                    TripleAgl.EncryptFile(inputFilePath, outputFilePath);
                    KeyByte = Rsa.Encrypt(TripleAgl.Key, false);
                    IvByte = Rsa.Encrypt(TripleAgl.IV, false);
                }

                if (cbbAlgorithm.SelectedItem.Equals("AES"))
                {
                    RijndaelAlgorithm RijAgl = new RijndaelAlgorithm(pad, cipher);
                    RijAgl.EncryptFile(inputFilePath, outputFilePath);
                    KeyByte = Rsa.Encrypt(RijAgl.Key, false);
                    IvByte = Rsa.Encrypt(RijAgl.IV, false);
                }

                /****************/
              
                FileStream filestream = new FileStream(outputFilePath, FileMode.Append, FileAccess.Write);
                filestream.Write(KeyByte, 0, KeyByte.Length);
                filestream.Write(IvByte, 0, IvByte.Length);
                filestream.WriteByte((byte)cbbAlgorithm.SelectedIndex);
                filestream.WriteByte((byte)cbbPaddingSchema.SelectedIndex);
                filestream.WriteByte((byte)cbbOperationMode.SelectedIndex);
                filestream.WriteByte((byte)Zip);
                filestream.Close();

                FileHelper.ShowMessage("Encrypt successful", MessageBoxImage.Information);
                File.Delete(inputFilePath);
                this.Close();
            }
            catch (Exception ex)
            {
                FileHelper.ShowMessage(ex.Message, MessageBoxImage.Error);
            }


        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            List<string> algirothms = new List<string>();
            algirothms.Add("DES");
            algirothms.Add("TripleDES");
            algirothms.Add("AES");
            cbbAlgorithm.ItemsSource = algirothms;
            cbbAlgorithm.SelectedIndex = 0;

            List<CipherMode> operationModes = new List<CipherMode>();            
            operationModes.Add(CipherMode.CBC);
            operationModes.Add(CipherMode.CFB);
            operationModes.Add(CipherMode.CTS);
            operationModes.Add(CipherMode.ECB);
            operationModes.Add(CipherMode.OFB);
            cbbOperationMode.ItemsSource = operationModes;
            cbbOperationMode.SelectedIndex = 0;

            List<PaddingMode> paddingSchemas = new List<PaddingMode>();

            paddingSchemas.Add(PaddingMode.ANSIX923);
            paddingSchemas.Add(PaddingMode.ISO10126);
            paddingSchemas.Add(PaddingMode.None);            
            paddingSchemas.Add(PaddingMode.PKCS7);
            paddingSchemas.Add(PaddingMode.Zeros);
            cbbPaddingSchema.ItemsSource = paddingSchemas;
            cbbPaddingSchema.SelectedIndex = 0;

            cbbUser.ItemsSource = Data.ApplicationData.Users;
            cbbUser.SelectedIndex = 0;

            if(!StartDirectory.EndsWith("\\")) 
            {
                StartDirectory += "\\";
            }
            txtDesination.Text = StartDirectory + "secure.enc";
        }
    }
}
